package cn.jtool.dig.server.comm.tunnel;

import cn.jtool.dig.common.model.Session;
import cn.jtool.dig.common.netty.CtxUtils;
import cn.jtool.dig.common.netty.SessionManager;
import cn.jtool.dig.server.dao.entity.License;
import cn.jtool.dig.server.dao.entity.PortMapping;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Objects;

@Slf4j
@Component
@ChannelHandler.Sharable
public class TunnelConnHander extends ChannelInboundHandlerAdapter {

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("[tunnel]连接激活, 远程地址: {}", ctx.channel().remoteAddress());
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        License license = CtxUtils.getAttribute(ctx, TunnelAttrKey.LICENSE);
        if(Objects.nonNull(license)){
            log.info("[tunnel]连接断开, 转发名: {}, 远程地址: {}", license.getLicenseName(), CtxUtils.getAddress(ctx));
        }else{
            log.info("[tunnel]连接断开, 远程地址: {}", CtxUtils.getAddress(ctx));
        }
        SessionManager.removeSession(CtxUtils.getAttribute(ctx, TunnelAttrKey.SESSION_ID));
        // 内部链路断开后, 需要断开相关联的真实链路
        List<Session> sessions = SessionManager.getSession(Session.SessionType.REAL);
        if(CollectionUtils.isNotEmpty(sessions)){
            sessions.stream().filter(r -> Objects.equals(r.getLicenseId(), license.getId())).toList().forEach(Session::disconnect);
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.error("[tunnel]连接异常, 远程地址: {}", ctx.channel().remoteAddress(), cause);
        this.channelInactive(ctx);
    }
}
